/*
 * Copyright 2019 Sergey Ivanov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sergivonavi.materialbanner.internal;

import com.sergivonavi.materialbanner.ResourceTable;
import ohos.agp.components.*;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;

public class ButtonsContainer extends ComponentContainer implements Component.EstimateSizeListener,
        ComponentContainer.ArrangeListener {
    private static final int    HORIZONTAL   = 0;
    private static final int    VERTICAL     = 1;
    private              int    mButtonMarginEnd;
    private              int    mButtonMarginBottom;
    private              Button mLeftButton;
    private              Button mRightButton;
    private              int    mOrientation = HORIZONTAL;

    public ButtonsContainer(Context context) {
        this(context, null);
    }

    public ButtonsContainer(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public ButtonsContainer(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(context);
    }

    private void init(Context context) {
        mButtonMarginEnd = getDimen(ResourceTable.Integer_mb_button_margin_end);
        mButtonMarginBottom = getDimen(ResourceTable.Integer_mb_button_margin_bottom);
        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout
                .LayoutConfig(LayoutConfig.MATCH_CONTENT, LayoutConfig.MATCH_CONTENT);
        // left button
        mLeftButton = new Button(context);
        mLeftButton.setMaxTextLines(1);
        mLeftButton.setMinWidth(0);
        mLeftButton.setLayoutConfig(layoutConfig);
        mLeftButton.setVisibility(HIDE);
        mLeftButton.setTextSize(getDimen(ResourceTable.Integer_mb_button_text_size));
        mLeftButton.setPaddingLeft(30);
        mLeftButton.setPaddingRight(30);
        mLeftButton.setPaddingTop(21);
        mLeftButton.setPaddingBottom(21);

        // right button
        mRightButton = new Button(context);
        mRightButton.setMaxTextLines(1);
        mRightButton.setMinWidth(0);
        mRightButton.setLayoutConfig(layoutConfig);
        mRightButton.setVisibility(HIDE);
        mRightButton.setTextSize(getDimen(ResourceTable.Integer_mb_button_text_size));
        mRightButton.setPaddingLeft(30);
        mRightButton.setPaddingRight(30);
        mRightButton.setPaddingTop(21);
        mRightButton.setPaddingBottom(21);
        // add button
        addComponent(mLeftButton);
        addComponent(mRightButton);

        // 测量
        setEstimateSizeListener(this);

        // 布局
        setArrangeListener(this);
    }


    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        int widthUsed = 0;
        if (mLeftButton.getVisibility() != HIDE) {
            mLeftButton.estimateSize(mLeftButton.getWidth(), mLeftButton.getHeight());
            widthUsed += mLeftButton.getEstimatedWidth() + mButtonMarginEnd;
        }

        if (mRightButton.getVisibility() != HIDE) {
            mRightButton.estimateSize(mRightButton.getWidth(), mRightButton.getHeight());
            widthUsed += mRightButton.getEstimatedWidth() + mButtonMarginEnd;
        }

        // Allow orientation change only when the both buttons are not hidden
        if (mLeftButton.getVisibility() != HIDE && mRightButton.getVisibility() != HIDE) {
            if (widthUsed > EstimateSpec.getSize(widthMeasureSpec)) {
                mOrientation = VERTICAL;
            } else {
                mOrientation = HORIZONTAL;
            }
        }

        if (mOrientation == VERTICAL) {
            measureVertical();
        } else {
            measureHorizontal();
        }
        return true;
    }

    /**
     * Measures the children when the orientation of this view is set to {@link #VERTICAL}.
     */
    private void measureVertical() {
        int widthUsed = 0;
        int heightUsed = 0;

        if (mLeftButton.getVisibility() != HIDE) {
            widthUsed = mLeftButton.getEstimatedWidth() + mButtonMarginEnd;
            heightUsed += mLeftButton.getEstimatedHeight() + mButtonMarginBottom;
        }

        if (mRightButton.getVisibility() != HIDE) {
            widthUsed = Math.max(widthUsed, (mRightButton.getEstimatedWidth()));
            heightUsed += mRightButton.getEstimatedHeight() + mButtonMarginBottom;
        }
        setEstimatedSize(widthUsed, heightUsed);
    }

    /**
     * Measures the children when the orientation of this view is set to {@link #HORIZONTAL}.
     */
    private void measureHorizontal() {
        int widthUsed = 0;
        int heightUsed = 0;

        if (mLeftButton.getVisibility() != HIDE) {
            widthUsed += mLeftButton.getEstimatedWidth() + mButtonMarginEnd;
            heightUsed = mLeftButton.getEstimatedHeight() + mButtonMarginBottom;
        }

        if (mRightButton.getVisibility() != HIDE) {
            widthUsed += mRightButton.getEstimatedWidth() + mButtonMarginEnd;
            heightUsed = Math.max(heightUsed, (mRightButton.getEstimatedHeight() + mButtonMarginBottom));
        }
        setEstimatedSize(widthUsed, heightUsed);
    }


    @Override
    public boolean onArrange(int i, int i1, int i2, int i3) {
        if (mOrientation == VERTICAL) {
            layoutVertical();
        } else {
            layoutHorizontal();
        }
        return true;
    }

    /**
     * Position the children during a layout pass if the orientation of this view is set to
     * {@link #VERTICAL}.
     */
    private void layoutVertical() {
        int top = 0;
        int lBtnRight = getEstimatedWidth() - mButtonMarginEnd;
        int lBtnLeft = lBtnRight - mLeftButton.getEstimatedWidth();
        int rBtnRight = getEstimatedWidth();
        int rBtnLeft = rBtnRight - mRightButton.getEstimatedWidth();
        int rBtnHeight = mLeftButton.getEstimatedHeight();

        if (mRightButton.getVisibility() != HIDE) {
            mRightButton.arrange(rBtnLeft, top, rBtnRight, rBtnHeight);
            top += mRightButton.getEstimatedHeight();
        }

        if (mLeftButton.getVisibility() != HIDE) {
            mLeftButton.arrange(lBtnLeft, top, lBtnRight, top + rBtnHeight);
        }
    }

    /**
     * Position the children during a layout pass if the orientation of this view is set to
     * {@link #HORIZONTAL}.
     */
    private void layoutHorizontal() {
        int lBtnLeft = 0;
        int lBtnRight = mLeftButton.getEstimatedWidth();
        int rBtnLeft = lBtnRight + mButtonMarginEnd;
        int rBtnRight = mRightButton.getEstimatedWidth();

        if (mLeftButton.getVisibility() != HIDE) {
            mLeftButton.arrange(lBtnLeft, 0, lBtnRight, mLeftButton.getEstimatedHeight());
        }

        if (mRightButton.getVisibility() != HIDE) {
            mRightButton.arrange(rBtnLeft, 0, rBtnRight, mRightButton.getEstimatedHeight());
        }
    }

    public void setOrientation(int orientation) {
        if (mOrientation != orientation) {
            mOrientation = orientation;
            postLayout();
        }
    }

    public int getOrientation() {
        return mOrientation;
    }

    public Button getLeftButton() {
        return mLeftButton;
    }

    public Button getRightButton() {
        return mRightButton;
    }

    private int getDimen(int dimenId) {
        int dimes = 0;
        try {
            int vp = getContext().getResourceManager().getElement(dimenId).getInteger();
            DisplayAttributes da = DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes();
            dimes = Math.round(da.densityPixels * vp);
        } catch (IOException | NotExistException | WrongTypeException e) {
            e.printStackTrace();
        }
        return dimes;
    }
}
